package container

import (
	"gitee.com/amoyx/cloud-provider/pkg/cloud/tencent/models"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
	qtke "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tke/v20180525"
	"strings"
)

type TkeGreeter interface {
	TKE(region string) TkeInterface
}

type TkeInterface interface {
	DescribeCluster(id string) (result models.TkeClusterItem, err error)
	ListClusterByName(name string) (list []models.TkeClusterItem, err error)
	ListAllCluster() (list []models.TkeClusterItem, err error)
	GetClusterKubeConfig(id string, isExtranet bool) (result string, err error)
	GetUpgradableVersion(id string) (list []string, err error)
}

type tke struct {
	region    string
	container *Container
	client    *qtke.Client
}

func newTke(c *Container, region string) TkeInterface {
	t := &tke{
		region:    region,
		container: c,
	}
	cpf := profile.NewClientProfile()
	cpf.HttpProfile.Endpoint = string(TKEEndPoint)
	client, _ := qtke.NewClient(c.credential, region, cpf)
	t.client = client
	return t
}

func (t *tke) CreateCluster() {

}

func (t *tke) DescribeCluster(id string) (result models.TkeClusterItem, err error) {
	list, err := t.query(map[string]string{"ClusterId": id})
	if len(list) > 0 {
		result = list[0]
	}
	return
}

func (t *tke) ListClusterByName(name string) (list []models.TkeClusterItem, err error) {
	return t.query(map[string]string{"ClusterName": name})
}

func (t *tke) ListAllCluster() (list []models.TkeClusterItem, err error) {
	return t.query(map[string]string{})
}

// EnableWanAddr 开启APIServer地址
func (t *tke) EnableWanAddr(id string, isWanAddr bool, domain string) (err error) {
	request := qtke.NewCreateClusterEndpointRequest()
	request.ClusterId = common.StringPtr(id)
	request.IsExtranet = common.BoolPtr(isWanAddr)
	if strings.TrimSpace(domain) != "" {
		request.Domain = common.StringPtr(domain)
	}
	_, err = t.client.CreateClusterEndpoint(request)
	return
}

// Delete 删除容器集群
func (t *tke) Delete(id string) (err error) {
	request := qtke.NewDeleteClusterRequest()
	request.ClusterId = common.StringPtr(id)
	request.InstanceDeleteMode = common.StringPtr("retain")
	_, err = t.client.DeleteCluster(request)
	return
}

// GetUpgradableVersion 获取可升级版本
func (t *tke) GetUpgradableVersion(id string) (list []string, err error) {
	request := qtke.NewDescribeAvailableClusterVersionRequest()
	request.ClusterId = common.StringPtr(id)
	response, err := t.client.DescribeAvailableClusterVersion(request)
	if err != nil {
		return
	}
	for _, val := range response.Response.Versions {
		list = append(list, *val)
	}
	return
}

// GetClusterKubeConfig 获取集群kubeConfig内容
func (t *tke) GetClusterKubeConfig(id string, isExtranet bool) (result string, err error) {
	request := qtke.NewDescribeClusterKubeconfigRequest()
	request.ClusterId = common.StringPtr(id)
	request.IsExtranet = common.BoolPtr(isExtranet)
	response, err := t.client.DescribeClusterKubeconfig(request)
	if err != nil {
		return
	}
	result = *response.Response.Kubeconfig
	return
}

// GetClusterLevelInfo 获取集群等级信息
func (t *tke) GetClusterLevelInfo(id string) (result models.TkeClusterLevelAttribute, err error) {
	request := qtke.NewDescribeClusterLevelAttributeRequest()
	request.ClusterID = common.StringPtr(id)
	response, err := t.client.DescribeClusterLevelAttribute(request)
	if err != nil {
		return
	}
	if len(response.Response.Items) > 0 {
		item := response.Response.Items[0]
		result = models.TkeClusterLevelAttribute{
			Name:           *item.Name,
			Alias:          *item.Alias,
			NodeCount:      *item.NodeCount,
			PodCount:       *item.PodCount,
			ConfigMapCount: *item.ConfigMapCount,
			RSCount:        *item.RSCount,
			CRDCount:       *item.CRDCount,
			Enable:         *item.Enable,
			OtherCount:     *item.OtherCount,
		}
	}
	return
}

func (t *tke) query(args map[string]string) (list []models.TkeClusterItem, err error) {
	request := qtke.NewDescribeClustersRequest()
	request.Offset = common.Int64Ptr(0)
	request.Limit = common.Int64Ptr(100)
	var filters []*qtke.Filter
	for key, val := range args {
		filters = append(filters, &qtke.Filter{
			Name:   common.StringPtr(key),
			Values: common.StringPtrs([]string{val}),
		})
	}
	request.Filters = filters
	response, err := t.client.DescribeClusters(request)
	if err != nil {
		return
	}
	for _, row := range response.Response.Clusters {
		ns := row.ClusterNetworkSettings
		var subnets []string
		for _, v := range ns.Subnets {
			subnets = append(subnets, *v)
		}
		network := models.TkeClusterNetworkSettings{
			ClusterCIDR:               *ns.ClusterCIDR,
			IgnoreClusterCIDRConflict: *ns.IgnoreClusterCIDRConflict,
			MaxNodePodNum:             *ns.MaxNodePodNum,
			MaxClusterServiceNum:      *ns.MaxClusterServiceNum,
			Ipvs:                      *ns.Ipvs,
			VpcId:                     *ns.VpcId,
			Cni:                       *ns.Cni,
			KubeProxyMode:             *ns.KubeProxyMode,
			ServiceCIDR:               *ns.ServiceCIDR,
			Subnets:                   subnets,
			IgnoreServiceCIDRConflict: *ns.IgnoreServiceCIDRConflict,
			IsDualStack:               *ns.IsDualStack,
			Ipv6ServiceCIDR:           *ns.Ipv6ServiceCIDR,
			CiliumMode:                *ns.CiliumMode,
		}
		list = append(list, models.TkeClusterItem{
			ClusterId:              *row.ClusterId,
			ClusterName:            *row.ClusterName,
			ClusterDescription:     *row.ClusterDescription,
			ClusterVersion:         *row.ClusterVersion,
			ClusterOs:              *row.ClusterOs,
			ClusterType:            *row.ClusterType,
			ClusterNetworkSettings: network,
			ClusterNodeNum:         *row.ClusterNodeNum,
			ProjectId:              *row.ProjectId,
			ClusterStatus:          *row.ClusterStatus,
			ClusterMaterNodeNum:    *row.ClusterMaterNodeNum,
			ImageId:                *row.ImageId,
			ContainerRuntime:       *row.ContainerRuntime,
			CreatedTime:            *row.CreatedTime,
			DeletionProtection:     *row.DeletionProtection,
			EnableExternalNode:     *row.EnableExternalNode,
			ClusterLevel:           *row.ClusterLevel,
			RuntimeVersion:         *row.RuntimeVersion,
			ClusterEtcdNodeNum:     *row.ClusterEtcdNodeNum,
		})
	}
	return
}
